<?php

namespace app\api\controller\balance;

use think\Db;
use think\Log;

class Details
{

	use \app\common\traits\ToolTrait;

	/**
	 * 实例对象
	 * @var object
	 */
	protected static $instance;

	/**
	 * 默认配置
	 * @var array
	 */
	protected $conf  = [
		"user" 		=> "user",
		"log" 		=> "balance_log",
		"day_log" 	=> "balance_changes_day",
		"pro" 		=> "product",
		"buy" 		=> "equip_buy",
		"order"		=> "order",
		"borrow" 	=> "balance_borrow",
		"draw" 		=> "withdrawal_order",
		"earn"		=> "money_log"
	];

	/**
	 * 实例化
	 */
	public static function instance()
	{
		if (is_null(self::$instance)) {
			self::$instance = new static();
		}
		return self::$instance;
	}

	// ---------------------------------------------- 范围 --------------------------------------------------------

	/**
	 * 范围查询 - 统计
	 */
	public function range_account_totals($uid, $date)
	{
		if (!empty($uid) && !empty($date)) {
			$return = [];
			$ex = explode("_", $date);
			$where = "uid = {$uid} and  ( times >= " . strtotime($ex[0]) . " and times <= " . strtotime($ex[1]) . " )";
			$query = Db::name($this->conf["day_log"])
				->where($where)
				->field("sum(income) income,sum(in_nums) income_bit,sum(expend) expend,sum(ex_nums) expend_bit")
				->select();
			if ($query) {
				for ($i = 0; $i < count($query); $i++) {
					$query[$i]["after"] = Db::name($this->conf["day_log"])
						->where("uid = {$uid} and times <= " . strtotime($ex[1]))
						->order("times DESC")->value("afters");
					$return = $query[$i];
				}
			}
			return $return;
		}
		return false;
	}

	/**
	 * 范围查询 - 列
	 */
	public function rangsLists($uid = 0, $times = "", $typs = 1)
	{
		$data = [];
		if (!empty($uid) && !empty($times) && !empty($typs)) {
			$where = "";

			$ex = explode("_", $times);
			$where = " and  ( times >= " . strtotime($ex[0]) . " and times <= " . strtotime($ex[1]) . " )";
			$field = "balance_type_id typs,earn_type isChg";
			$req = Db::name($this->conf['log'])
				->field($field)
				->where("main_id = " . $uid . " and balance_type_id not in (1,2,3,9) and earn_type = {$typs}" . $where)
				->group("balance_type_id,earn_type")
				->select();
			if ($req) {
				foreach ($req as $key => $val) {
					$data[] = $val;
					$data[$key]["name"] =  $this->format_nick($val["typs"], $val["isChg"]);
					$data[$key]["total"] = [
						"total" => $this->types_total($uid, $val["typs"], $val["isChg"], $times),
						"counts" => 1,
					];
					$data[$key]["balanceTypeNums"] = 1;
					$data[$key]["balanceTypeData"] = $this->types_group_data($uid, $val["typs"], $val["isChg"], $times);
				}
			}
			if ($typs == 1) {
				$pro_income_data = $this->range_income_bit($uid, $times, $typs);
				$data = array_merge($pro_income_data, $data);
			}
		}
		return $data;
	}

	/**
	 * 收益 - 分润、达标、流量卡、调价
	 */
	public function range_income_bit($uid, $times, $typs = 1)
	{
		$data = [];
		if (!empty($uid) && !empty($times)) {
			$str = "";
			$ex = explode("_", $times);
			$str = " and (trading_time >= " . strtotime($ex[0]) . " and  trading_time <= " . strtotime($ex[1] . " +1 day") . ")";
			$field = "product_id proid";
			$req = Db::name($this->conf['earn'])
				->field($field)
				->where("main_id = " . $uid  . $str)
				->group("product_id")
				->select();
			$pro = Db::name($this->conf["pro"])->column("name", "id");
			foreach ($req as $key => $val) {
				$data[] = $val;
				$data[$key]["name"] = $pro[$val["proid"]];
				$data[$key]["total"] = [
					"total" => $this->produc_total($uid, $val["proid"], $times),
					"counts" => 1,
				];
				$data[$key]["balanceTypeNums"] = 1;
				$data[$key]["balanceTypeData"] = $this->earn_types_data($uid, $val["proid"], $times, $typs);
			}
		}
		return $data;
	}

	/**
	 * 范围 - 详情
	 */
	public function range_account_details($uid, $typs, $proid, $isChg, $date, $page)
	{
		// 1,2,3,9 分润、达标、流量卡、调价 
		$trade_income_arr = [1, 2, 3, 9];
		if (empty($uid)  || empty($isChg) || empty($date)) {
			return false;
		}
		$data = [];
		if (in_array($typs, $trade_income_arr)) {
			$data = $this->range_earn_details($uid, $typs, $proid, $date, $page);
		} else {
			$limit = 10;
			$offset = ($page - 1) * $limit;
			$ex = explode("_", $date);
			$where = "`status` = 1 and main_id = {$uid} and earn_type = {$isChg} and balance_type_id not in (1,2,3,9) ";
			$where .= " and balance_type_id = {$typs}  and  ( times >= " . strtotime($ex[0]) . " and times <= " . strtotime($ex[1]) . " )";
			$req = Db::name($this->conf["log"])->where($where)
				->field("balance_type_id,earn_type,product_id,money,create_time,mome,sn")
				->order("create_time DESC")
				->limit((int)$offset, $limit)
				->select();
			if (count($req)) {
				foreach ($req as $k => $vals) {
					$data[] = $vals;
					$data[$k]['mome'] = $this->format_nick($vals["balance_type_id"], $vals["earn_type"]);
					$data[$k]["create_time"] = date("Y-m-d H:i:s", $vals["create_time"]);
					$data[$k]["product_name"] = $this->nicks($uid, $vals["balance_type_id"], $vals["earn_type"], $vals["product_id"]);
				}
			}
		}
		return $data;
	}

	/**
	 * 收益 - 分润、达标、流量卡、调价
	 */
	public function range_earn_details($uid, $typs, $proid, $date, $page)
	{
		// 1,2,3,9 分润、达标、流量卡、调价 
		$exPro = explode("_", $proid);
		$exDate = explode("_", $date);
		$where = "main_id = {$uid} ";
		$where .= " and (trading_time >= " . strtotime($exDate[0]) . " and  trading_time < " . strtotime($exDate[1] . " +1 day") . ")";
		$where .= " and product_id = " . $exPro[0] . " and money_type = '" . $exPro[1] . "'";
		$where .= " and balance_type_id = {$typs}";

		$data = [];
		$limit = 10;
		$offset = ($page - 1) * $limit;
		$req = Db::name($this->conf["earn"])->where($where)
			->field("balance_type_id,money_type,product_id,1 earn_type,changes money,trading_time,mome,sn")
			->order("trading_time DESC")
			->limit((int)$offset, $limit)
			->select();
		if (count($req)) {
			$arr = config("earn_typs");
			foreach ($req as $k => $vals) {
				$data[] = $vals;
				$data[$k]['mome'] = $arr[$vals["balance_type_id"]] . "-"  . $arr[$vals["money_type"]] . "收益";
				$data[$k]["create_time"] = date("Y-m-d H:i:s", $vals["trading_time"]);
				$data[$k]["product_name"] = $vals["sn"];
			}
		}
		return $data;
	}

	// ---------------------------------------------- 单日 --------------------------------------------------------

	/**
	 * 日 - 账单
	 */
	public function days_account_total($uid, $date)
	{
		if (!empty($uid) && !empty($date)) {
			$where = ["uid" => $uid, "times" => strtotime($date)];
			$find = Db::name($this->conf["day_log"])
				->where($where)
				->field("income,in_nums income_bit,expend,ex_nums expend_bit,afters after")
				->find();
			if ($find) {
				return $find;
			}
		}
		return false;
	}

	/**
	 * 收入
	 */
	public function income($uid, $date)
	{
		$sum = 0;
		$req = Db::name($this->conf["log"])
			->where("earn_type = 1 and times <= " . strtotime($date) . " and status = 1 and main_id = {$uid}")
			->sum("money");
		if ($req) {
			$sum = $req;
		}
		return $sum;
	}

	/**
	 * 支出
	 */
	public function expend($uid, $date)
	{
		$sum = 0;
		$req = Db::name($this->conf["log"])
			->where("earn_type = 2 and times <= " . strtotime($date) . " and status = 1 and main_id = {$uid}")
			->sum("money");
		if ($req) {
			$sum = $req;
		}
		return $sum;
	}

	/**
	 * 日 - 账单统计
	 */
	public function days_account_count_bak($uid, $date)
	{
		if (!empty($uid) && !empty($date)) {
			$data = [
				'after' => '0.00',
				'income' => '0.00',
				'expend' => '0.00',
			];
			$where = "main_id = {$uid} and status =1 ";
			$where .= " and  times = " . strtotime($date);
			$req = Db::name($this->conf["log"])
				->where($where)
				->field("earn_type,sum(money) money")
				->group("earn_type")
				->select();
			if ($req) {
				for ($i = 0; $i < count($req); $i++) {
					if ($req[$i]["earn_type"] == 1) {
						$data["after"] = $req[$i]["money"];
						$data["income"] = $req[$i]["money"];
					} else {
						$data["expend"] = $req[$i]["money"];
					}
				}
			}
			return $data;
		}
		return false;
	}

	/**
	 * 表
	 * 1=分润,2=流量卡,3=达标,4=借款,5=还款,6=赠送,7=提现,8=认购,9=调价，10=采购
	 */
	public function table($typs)
	{

		$table = "";
		if (!empty($typs)) {
			switch ($typs) {
				case 4:
				case 5:
				case 6:
					$table = $this->conf["borrow"];
					break;
				case 7:
					$table = $this->conf["draw"];
					break;
				case 8:
					$table = $this->conf["buy"];
					break;
				case 10:
					$table = $this->conf["order"];
					break;
				default:
					break;
			}
		}
		return $table;
	}


	public $buy = [8]; // 认购
	public $bor = [4, 6];	// 借、赠
	public $rep = [5]; // 还
	public $ord	= [10]; // 采购
	public $drw = [7];  // 提现

	/**
	 * 昵称
	 */
	public function nicks($uid, $typs, $isChg, $id)
	{
		$return = "Unkown";
		try {
			$trade_income_arr = [1, 2, 3, 9];
			if (!in_array($typs, $trade_income_arr)) {
				if ($typs == 12 || $typs == 13) {
					$return = ($typs == 12 ? "运营资金" : ($typs == 13 ? "机具款" : "其它"));
				} else {
					$field = "";
					$table = $this->table($typs);
					switch (true) {
						case in_array($typs, $this->drw):
							$field = "sale_id";
							break;
						case in_array($typs, $this->buy):
							$field = "agid";
							$isChg == 2 && $field = "pid";
							break;
						case in_array($typs, $this->bor):
							$field = "loan_id";
							$isChg == 2 && $field = "bid";
							break;
						case in_array($typs, $this->rep):
							$field = "bid";
							$isChg == 2 && $field = "loan_id";
							break;
						case in_array($typs, $this->ord):
							$field = "user_id";
							if ($isChg == 2) {
								$id = $uid;
								$field = "pid";
								$table = $this->conf["user"];
							}
							$return = "采购";
							break;
					}
					if ($field) {
						$ids = Db::name($table)->where("id = {$id}")->value($field);
						$ids && $return = Db::name($this->conf["user"])->where("id = {$ids}")->value("nickname");
					}
				}
			}
		} catch (\Exception $e) {
			Log::write($e->getMessage());
		}
		return $return;
	}

	/**
	 * 账单明细
	 */
	public function account_details($uid, $typs, $proid, $isChg, $date, $start, $page)
	{

		// 1,2,3,9 分润、达标、流量卡、调价 
		$trade_income_arr = [1, 2, 3, 9];
		if (empty($uid)  || empty($isChg) || empty($date)) {
			return false;
		}
		$where = "`status` = 1 and main_id = {$uid} and earn_type = {$isChg} and balance_type_id not in (1,2,3,9)";
		if (!empty($start)) {
			$where .= " and (times >= " . strtotime($start) . " and times <= " . strtotime($date) . ")";
		} else {
			if (!empty($typs)) {
				$str = "";
				// if (in_array($typs, $trade_income_arr)) {
				// 	$str = " and product_id = " . $proid;
				// }
				$where .= " and balance_type_id = {$typs}  and  times = " . strtotime($date) . $str;
			} else {
				$where .= " and times = " . strtotime($date);
			}
		}
		$data = [];
		try {
			$limit = 10;
			$offset = ($page - 1) * $limit;
			$req = Db::name($this->conf["log"])->where($where)
				->field("balance_type_id,earn_type,product_id,money,create_time,mome,sn")
				// ->limit(($offset), $limit)
				->order("create_time DESC")
				->select();
			if (count($req)) {
				foreach ($req as $k => $vals) {
					$data[] = $vals;
					$data[$k]['mome'] = $this->format_nick($vals["balance_type_id"], $vals["earn_type"]);
					$data[$k]["create_time"] = date("Y-m-d H:i:s", $vals["create_time"]);
					$data[$k]["product_name"] = $this->nicks($uid, $vals["balance_type_id"], $vals["earn_type"], $vals["product_id"]);
					// if (in_array($vals["balance_type_id"], $trade_income_arr)) {
					// 	$data[$k]["product_name"] = $vals["sn"];
					// }
				}
			}
			if ($isChg == 1) {
				$earn = $this->earn_details($uid, $typs, $proid, $isChg, $date, $start);
				$data = array_merge($earn, $data);
			}
			$data = \app\api\controller\basics\Basics::instance()->array_page($data, $page);
		} catch (\Exception $e) {
			Log::write($e->getMessage());
		}
		return $data;
	}

	/**
	 *  收益 - 分润、达标、流量卡、调价 - 详情
	 */
	public function earn_details($uid, $typs, $proid, $isChg, $date, $start)
	{
		// 1,2,3,9 分润、达标、流量卡、调价 
		$trade_income_arr = [1, 2, 3, 9];
		$where = "main_id = {$uid} ";
		if (!empty($start)) {
			$where .= " and (trading_time >= " . strtotime($start) . " and trading_time < " .  strtotime($date . " +1 day") . ")";
		} else {
			if (!empty($typs)) {
				$str = "";
				if (in_array($typs, $trade_income_arr)) {
					$ex = explode("_", $proid);
					$str = " and product_id = " . $ex[0] . " and money_type = '" . $ex[1] . "'";
				}
				$where .= " and balance_type_id = {$typs}  and  from_unixtime(trading_time , '%Y-%m-%d') = '{$date}'" . $str;
			} else {
				$where .= " and from_unixtime(trading_time , '%Y-%m-%d') = '{$date}'";
			}
		}
		$data = [];
		try {
			$req = Db::name($this->conf["earn"])->where($where)
				->field("balance_type_id,money_type,product_id,1 earn_type,changes money,trading_time,mome,sn")
				->order("trading_time DESC")
				->select();
			if (count($req)) {
				$arr = config("earn_typs");
				foreach ($req as $k => $vals) {
					$data[] = $vals;
					$data[$k]['mome'] = $arr[$vals["balance_type_id"]] . "-"  . $arr[$vals["money_type"]] . "收益";
					$data[$k]["create_time"] = date("Y-m-d H:i:s", $vals["trading_time"]);
					$data[$k]["product_name"] = $vals["sn"];
					// if (in_array($vals["balance_type_id"], $trade_income_arr)) {
					// 	$data[$k]["product_name"] = $vals["sn"];
					// }
				}
			}
		} catch (\Exception $e) {
			Log::write($e->getMessage());
		}
		return $data;
	}

	/**
	 * 列表
	 */
	public function lists($uid = 0, $times = "", $typs = 1)
	{
		$data = [];
		if (!empty($uid) && !empty($times) && !empty($typs)) {
			$where = "";
			$where = " and  times = " . strtotime($times);
			$field = "balance_type_id typs,earn_type isChg";
			$req = Db::name($this->conf['log'])
				->field($field)
				->where("main_id = " . $uid . " and balance_type_id not in (1,2,3,9) and earn_type = {$typs}" . $where)
				->group("balance_type_id,earn_type")
				->select();
			if ($req) {
				foreach ($req as $key => $val) {
					$data[] = $val;
					$data[$key]["name"] =  $this->format_nick($val["typs"], $val["isChg"]);
					$data[$key]["total"] = [
						"total" => $this->types_total($uid, $val["typs"], $val["isChg"], $times),
						"counts" => 1,
					];
					$data[$key]["balanceTypeNums"] = 1;
					$data[$key]["balanceTypeData"] = $this->types_group_data($uid, $val["typs"], $val["isChg"], $times);
				}
			}
			if ($typs == 1) {
				$pro_income_data = $this->income_bit($uid, $times, $typs);
				$data = array_merge($pro_income_data, $data);
			}
		}
		return $data;
	}

	/**
	 * 收益 - 分润、达标、流量卡、调价
	 */
	public function income_bit($uid, $times, $typs = 1)
	{
		$data = [];
		if (!empty($uid) && !empty($times)) {
			$str = "";
			$str = " and  from_unixtime(trading_time , '%Y-%m-%d') = '{$times}'";
			$field = "product_id proid";
			$req = Db::name($this->conf['earn'])
				->field($field)
				->where("main_id = " . $uid  . $str)
				->group("product_id")
				->select();
			$pro = Db::name($this->conf["pro"])->column("name", "id");
			foreach ($req as $key => $val) {
				$data[] = $val;
				$data[$key]["name"] = $pro[$val["proid"]];
				$data[$key]["total"] = [
					"total" => $this->produc_total($uid, $val["proid"], $times),
					"counts" => 1,
				];
				$data[$key]["balanceTypeNums"] = 1;
				$data[$key]["balanceTypeData"] = $this->earn_types_data($uid, $val["proid"], $times, $typs);
			}
		}
		return $data;
	}

	/**
	 * 按收益类型 - 总
	 */
	public function earn_types_data($uid, $proid, $times, $typs)
	{
		$return = [];
		$str = "";
		$str = " and  from_unixtime(trading_time , '%Y-%m-%d') = '{$times}'";
		$ex = explode("_", $times);
		if (count($ex) > 1) {
			$str = " and (trading_time >= " . strtotime($ex[0]) . " and  trading_time <= " . strtotime($ex[1] . " +1 day") . " )";
		}
		$where = "main_id = {$uid} and product_id = {$proid}  " . $str;
		$return = Db::name($this->conf["earn"])
			->where($where)
			->field("balance_type_id typs,money_type,sum(changes) total")
			->group("balance_type_id , money_type")
			->select();
		$arr = config("earn_typs");
		foreach ($return as $k => $vals) {
			$return[$k]["isChg"] = $typs;
			$return[$k]["proid"] = $proid . "_" . $vals["money_type"];
			$return[$k]["name"] = $arr[$vals["typs"]] . "-" . $arr[$vals["money_type"]];
		}
		return $return;
	}

	/**
	 * 按类型 - 总
	 */
	public function types_total($uid, $typs, $isChg, $times)
	{
		$total = 0;
		$str = "";
		$str = " and  times = " . strtotime($times);
		$ex = explode("_", $times);
		if (count($ex) > 1) {
			$str = " and ( times >= " . strtotime($ex[0]) . " and times <= " . strtotime($ex[1]) . " )";
		}
		$where = "main_id = {$uid} and balance_type_id = {$typs} and earn_type = {$isChg} and  status = 1" . $str;
		$total = Db::name($this->conf["log"])
			->where($where)
			->sum("money");
		return $total;
	}

	/**
	 * 按类型 - 总
	 */
	public function types_group_data($uid, $typs, $isChg, $times)
	{
		$return = [];
		$str = "";
		$str = " and  times = " . strtotime($times);
		$ex = explode("_", $times);
		if (count($ex) > 1) {
			$str = " and ( times >= " . strtotime($ex[0]) . " and times <= " . strtotime($ex[1]) . " )";
		}
		$where = "main_id = {$uid} and balance_type_id = {$typs} and earn_type = {$isChg} and  status = 1" . $str;
		$return = Db::name($this->conf["log"])
			->field("balance_type_id typs,earn_type isChg,case earn_type when 1 then '收入' when 2 then '支出' end name,sum(money) total ,0 proid")
			->where($where)
			->select();
		return $return;
	}

	/**
	 * 收益 - 分润、达标、流量卡、调价 - 备份
	 */
	public function income_bit_bak($uid, $times, $typs)
	{
		$data = [];
		if (!empty($uid) && !empty($times)) {
			$str = "";
			$str = " and  times = " . strtotime($times);
			$field = "product_id proid";
			$req = Db::name($this->conf['log'])
				->field($field)
				->where("main_id = " . $uid . " and balance_type_id in (1,2,3,9) and earn_type = {$typs}" . $str)
				->group("product_id")
				->select();
			$pro = Db::name($this->conf["pro"])->column("name", "id");
			foreach ($req as $key => $val) {
				$data[] = $val;
				$data[$key]["name"] = $pro[$val["proid"]];
				$data[$key]["total"] = [
					"total" => $this->produc_total($uid, $val["proid"], $times),
					"counts" => 1,
				];
				$data[$key]["balanceTypeNums"] = 1;
				$data[$key]["balanceTypeData"] = $this->produc_typs_data($uid, $val["proid"], $times, $typs);
			}
		}

		return $data;
	}

	/**
	 * 按类型 - 总
	 */
	public function produc_typs_data($uid, $proid, $times, $typs)
	{
		$return = [];
		$str = "";
		$str = " and  times = " . strtotime($times);
		$where = "main_id = {$uid} and product_id = {$proid} and  balance_type_id in (1,2,3,9) and  status = 1" . $str;
		$return = Db::name($this->conf["log"])
			->where($where)
			->field("balance_type_id typs,sum(money) total")
			->group("balance_type_id")
			->select();
		$arr = config("earn_typs");
		foreach ($return as $k => $vals) {
			$return[$k]["isChg"] = $typs;
			$return[$k]["proid"] = $proid;
			$return[$k]["name"] = $arr[$vals["typs"]];
		}
		return $return;
	}

	/**
	 * 按类型 - 总
	 */
	public function produc_total($uid, $proid, $times)
	{
		$total = 0;
		$str = "";
		$str = " and  times = " . strtotime($times);
		$ex = explode("_", $times);
		if (count($ex) > 1) {
			$str = " and (times >= " . strtotime($ex[0]) . " and  times < " . strtotime($ex[1] . " +1 day") . " )";
		}
		$where = "main_id = {$uid} and product_id = {$proid} and  balance_type_id in (1,2,3,9) and  status = 1" . $str;
		$total = Db::name($this->conf["log"])
			->where($where)
			->sum("money");
		return $total;
	}

	public function format_nick($typs, $isChg)
	{
		$nick = config("earn_typs." . $typs);
		switch ($typs) {
			case 4:
			case 5:
			case 6:
				$nick .= ($isChg == 1 ? "入" : ($isChg == 2 ? '出' : "其它"));
				break;
			default:
				$nick .= ($isChg == 1 ? "收入" : ($isChg == 2 ? '支出' : "其它"));
				break;
		}
		return $nick;
	}
}
